package com.bitin.adorn.common.orm.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.persistence.*;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 实体通用父类
 *
 * @author Mr.Lu
 * @since 2024/12/05 16:45
 */
@Data
@Accessors(chain = true)
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditableModel implements Serializable {
    /**
     * 主键
     * <p>
     * AUTO:     默认值,主键由程序控制
     * IDENTITY: 数据库自动增长, Oracle不支持这种方式 ORACLE 靠序列来提供类似自增长的功能
     * SEQUENCE: 通过数据库的序列产生主键, MYSQL不支持 MYSQL没有序列的概念
     * Table:    提供特定的数据库产生主键
     */
    @Id
    @GenericGenerator(name = "snowflake", strategy = "com.bitin.adorn.config.orm.SnowflakeIdGenerator")
    @GeneratedValue(generator = "snowflake")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    @Column(name = "id", nullable = false, length = 64)
    protected String id;

    // @Version 由于本身有乐观锁机制，这个我们测试的时候先注释掉，改⽤⼿动设置的值；
    protected Long version;

    @Column(name = "deleted", nullable = false)
    protected boolean deleted;

    /**
     * 创建时间
     */
    //@Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    @Column(name = "created_time", nullable = false, updatable = false, length = 8)
    protected LocalDateTime createdTime;

    /**
     * 上次更新时间
     */
    //@Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate
    @Column(name = "last_modified_time", nullable = false, length = 8)
    protected LocalDateTime lastModifiedTime;

    @CreatedBy
    @Column(name = "created_user_id", nullable = false, length = 36)
    protected String createdUserId;

    @LastModifiedBy
    @Column(name = "last_modified_user_id", nullable = false, length = 36)
    protected String lastModifiedUserId;

    // 这个可能会被 AuditingEntityListener 覆盖，为了⽅便测试，我们先注释掉
//    @PreUpdate
//    public void preUpdate() {
//        System.out.println("preUpdate::" + this);
//        this.setCreatedUserId("200");
//    }
//
//    @PostUpdate
//    public void postUpdate() {
//        System.out.println("postUpdate::" + this);
//    }
//
//    @PreRemove
//    public void preRemove() {
//        System.out.println("preRemove::" + this);
//    }
//
//    @PostRemove
//    public void postRemove() {
//        System.out.println("postRemove::" + this);
//    }
//
//    @PostLoad
//    public void postLoad() {
//        System.out.println("postLoad::" + this);
//    }
}
